package com.dtflys.easyel.runtime.eval;

import com.dtflys.easyel.antlr.EasyElParser;
import com.dtflys.easyel.ast.ASTBinaryExpression;
import com.dtflys.easyel.exception.EasyElEvalException;
import com.dtflys.easyel.runtime.EasyElRuntimeContext;
import com.dtflys.easyel.utils.MetaHelper;
import org.antlr.v4.runtime.Token;

/**
 * 比较求值器
 * @author gongjun[jun.gong@thebeastshop.com]
 * @since v1.0.0
 */
public class CompareEvaluator {


    public Boolean evaluate(EasyElRuntimeContext context, ASTBinaryExpression node, Object left, Object right) {
        left = MetaHelper.wrap(left);
        right = MetaHelper.wrap(right);

        Class leftClass = left.getClass();
        Class rightClass = right.getClass();
        Token op = node.getOperation();

        if (left instanceof Comparable && right instanceof Comparable) {
            Comparable leftCom = (Comparable) MetaHelper.wrap(left);
            Comparable rightCom = (Comparable) MetaHelper.wrap(right);
            switch (op.getType()) {
                case EasyElParser.GT:
                    return leftCom.compareTo(rightCom) > 0;
                case EasyElParser.GE:
                    return leftCom.compareTo(rightCom) >= 0;
                case EasyElParser.LT:
                    return leftCom.compareTo(rightCom) < 0;
                case EasyElParser.LE:
                    return leftCom.compareTo(rightCom) <= 0;
                case EasyElParser.EQ:
                    return leftCom.compareTo(rightCom) == 0;
                case EasyElParser.NOT_EQ:
                    return leftCom.compareTo(rightCom) != 0;
            }
        }
        throw new EasyElEvalException(context, node,
                "operator " + op.getText() + " do not support for type " + leftClass + " and " + rightClass);
    }

}
